<?php
/**
 * Created by PhpStorm.
 * User: yuanjie
 * Date: 15/9/9
 * Time: 下午7:26
 */
class Common
{
    function __construct(){
        date_default_timezone_set('Asia/Shanghai');
    }

    public static function generateCode($length = 4) {
        return rand(pow(10,($length-1)), pow(10,$length)-1);
    }

    public static function num2DateTime($num,$format = "Y-m-d H:i:s"){
        return date($format,$num);
    }

    public static function datetime2Num($datetime){
        return strtotime($datetime);
    }

    public static function createOrderId($length = 4){
        return time().rand(pow(10,($length-1)), pow(10,$length)-1);
    }

    public static function createId($length = 4){
        return date("YmdHis",time()).rand(pow(10,($length-1)), pow(10,$length)-1);
    }

    public static function currentTimeString(){
        return date("Y-m-d H:i:s",time());
    }
    /**
     * @Author:      lyt
     * @DateTime:    2016-07-21 13:09:32
     * @Description: 把耗材的售价向上取整
     */
    public static function upFow($amount){
        return ceil((Int)$amount/100)*100;
    }

    /**
     * @Author:      lyt
     * @DateTime:    2016-08-19 13:37:32
     * @Description: 获取第一个 能被整除 的最大数 都不能除尽返回-1
     */
    public static function getfisrtNum($amount,$number){
        for($i=$amount;$i>0;$i--){
            if($i%$number==0)
                return $i;
        }
        return -1;
    }

    public static function getPdfName()
    {
        return time() . '-' . rand(1, 99999) . '.pdf';
    }

    public static function make($pwd){
        return strtoupper(md5($pwd));
    }

    public static function getImageName()
    {
        return time() . '-' . rand(1, 99999) . '.png';
    }
    public static function getFileName()
    {
        return time() . '-' . rand(1, 99999);
    }
    public static function array_get_or($array,$key,$default_value){
        if(isset($array[$key])){
            $value=$array[$key];
            if($value){
                return $value;
            }
        }
        return $default_value;
    }
    public static function get_client_ip(){
        $cip = "unknown";
        if($_SERVER['REMOTE_ADDR']){
            $cip = $_SERVER['REMOTE_ADDR'];
        }else if(getenv("REMOTE_ADDR")){
            $cip = getenv("REMOTE_ADDR");
        }
        return $cip;
    }

    //用于提醒按日期返回给前端数据处理
    public static function remind_show_date($info){
        $info_array = [];
        if(!empty($info)){
            foreach($info as $value){
                $v_date = date("Y-m-d", strtotime($value['remind_at']));
                $array[$v_date][] = $value;
            }
            foreach ($array as $k=>$v) {
                $info_array[$k] = ['date'=>$k,'item_arr'=>$v];
            }
        }
        return $info_array;
    }

    /**
     * 解密
     * 反向：对KEY做MD5加密，用加密后的KEY对传递的JSON字符串做DES加密
     */
    public static function MD5AndDES($result){
        $key = Common::getConfigKey();
        //将收到的密文字符串（16进制）转 字符串
        $iv = Common::getIv();
        Log::debug(['key'=>$key,'iv'=>$iv]);
        $res_str = Common::decrypt($key,$result,$iv);
        Log::debug(['解密结果'=>$res_str]);
        return $res_str;
    }

    /**
     * 获取加密key
     */
    public static function getConfigKey(){
        $key = Config::get('config.suixingpay_key');
        return Common::MD5Key($key);
    }

    /**
     * 对KEY做MD5加密
     */
    public static function MD5Key($key){
        return md5($key);
    }

    /**
     * 将收到的密文字符串（16进制）转 字符串
     */
    public static function decrypt($key, $value,$iv){
        try {
            $value = hex2bin(strtoupper($value));
            $des = new CryptDes($key,$iv);//（秘钥向量，混淆向量）
            $output = $des->decrypt($value);
            return $output;
        } catch (Exception $exception) {
            Log::error($exception);
        }
        return null;
    }

    public static function getIv(){
        return Config::get('config.suixingpay_iv');
    }

    /**
     * 验证签名
     */
    public static function verifySign($sign,$sig_str){
        $prv_path = Config::get('config.suixingpay_prv_pem');
        $prv_key = Common::getPemKey($prv_path);
        if(!$prv_key){
            Log::debug('suixingpay had no prv key !');
            return false;
        }
        $sig = Common::sign($sig_str,$prv_key);
//        print_r($sig . "\n");
//        print_r($sign . "\n");
//        print_r($sig == $sign);exit;
        if($sig && $sig == $sign){
//            print_r(123);exit;
            $boo = true;
        }
        return $boo;
    }

    /**
     * 验证签名1
     */
    public static function verifySign1($sign,$sig_str){
        $pub_path = Config::get('config.suixingpay_pub_pem');
        $pub_content = file_get_contents($pub_path);
        $pub_key = openssl_pkey_get_public($pub_content);
        Log::debug(['接到的 sign'=>$sign,'sign 包含的数据'=>$sign]);
        $sign = base64_decode($sign);//得到的签名
        Log::debug(['base64_decode后的 sign'=>$sign]);
        $result = openssl_verify($sig_str,$sign,$pub_key);
        Log::debug(['验签结果'=>$result]);
        $result = (bool)$result;
        openssl_free_key($pub_key);
        return $result;
    }

    /**
     * 验证签名2
     * 服务器返回json数据格式如下
    {"tranSts":"S","tranTm":"092622","authCode":"376609","batNo":"000006","sign":"B64BDC6E73AD0A3869206AEDE2996D37","trmNo":"40000048","paySource":"02","cardNo":"436742******6872","feeAmt":0,"tranSeqNo":"71bcf238476c44f285d16da6860acd31","mno":"836567970110018","tranType":"0001","tranAmt":0.06,"ouuid":"","posSeqNo":"125686","tranDt":"20170306","searchNo":"170306850380"}
    先把sign节点提出来，去空后，把json按A-z排序拼接成url字符串
    authCode=376609&batNo=000006&cardNo=436742******6872&feeAmt=0&mno=836567970110018&paySource=02&posSeqNo=125686&searchNo=170306850380&tranAmt=0.06&tranDt=20170306&tranSeqNo=71bcf238476c44f285d16da6860acd31&tranSts=S&tranTm=092622&tranType=0001&trmNo=40000048&
    再进行MD5加密，转大写 ===》 B64BDC6E73AD0A3869206AEDE2996D37（签文）
    2017-09-12
     */
    public static function verifySign2($sign,$sig_str){
        $result = false;
        $sig = strtoupper(md5($sig_str));
        Log::debug(['接到的 sign'=>$sign,'转换完的 sign'=>$sig,'sign 包含的数据'=>$sig_str]);
        if($sig == $sign){
            $result = true;
        }
        return $result;
    }

    /**
     * 获取public key
     */
    public static function getPemKey($file_path){
        if(file_exists($file_path)) {
            $str = file_get_contents($file_path);//将整个文件内容读入到一个字符串中
//            $str = preg_replace(["/\\-{5}[\\w\\s]+\\-{5}[\\r\\n|\\n]/"],"",$str);
            $key = openssl_get_privatekey($str);
            return $key;
        }
        return '';
    }

    /**
     * 对 pub_key 加密
     */
    public static function RSAKey($key){
        $key = base64_decode($key);
        return $key;
    }
    static function sign($strData, $privateKey) {
        if (!openssl_get_privatekey($privateKey)) {
            echo 'encryptTaiping openssl_get_privatekey failed.';
            return false;
        }
        $signature = '';
        if (!openssl_sign($strData, $signature, $privateKey)) {
            echo 'openssl_sign failed.';
            return false;
        }
        openssl_free_key($privateKey);
        $signature = base64_encode($signature);
        return $signature;
    }
    /**
     * 拼字符串
     */
    public static function getStr($res_arr_no_sign){
        $signature = "";
        ksort($res_arr_no_sign);
        foreach($res_arr_no_sign as $key=>$val){
            if($val !== "") {
                $signature .= $key;
                $signature .= '=';
                $signature .= $val;
                $signature .= '&';
            }
        }
        $signature = trim($signature);
        return $signature;
    }
    /**
     * 处理字符串
     */
    public static function handStr($str){
        if(str_contains($str,"<string>")) {
            $str = substr($str,8,strlen($str));
        }
        if(str_contains($str,"</string>")) {
            $str = substr($str,0,strlen($str) - 9);
        }
        return $str;
    }
    /**
     * Add by lizhaoyao
     * Add at 2016-07-07 10:43
     * 由于 一般在PHP5.4中对json中中文转码直接用了json_encode($data,JSON_UNESCAPED_UNICODE)
     * 而 php5.3中 JSON_UNESCAPED_UNICODE 这个值是不存在的 所以要自己写一个兼容函数
     * 对变量进行 JSON 编码
     * @param mixed value 待编码的 value ，除了resource 类型之外，可以为任何数据类型，该函数只能接受 UTF-8 编码的数据
     * @return string 返回 value 值的 JSON 形式
     * */
    public static function json_encode_ex( $value)
    {
        $str = json_encode( $value);
        $str =  preg_replace_callback(
            "#\\\u([0-9a-f]{4})#i",
            function( $matchs)
            {
                return  iconv('UCS-2BE', 'UTF-8',  pack('H4',  $matchs[1]));
            },
            $str
        );
        return  $str;
    }
    /**
     * 金蝶用到
     */
    public static function getSignString($sign_array){
        $sign_first = '';
        if(isset($sign_array['apiSKey'])){$sign_first .= $sign_array['apiSKey'];}
        if(isset($sign_array['data'])){
            //排序
            foreach($sign_array['data'] as $val){
                $sign_first .= $val;
            }
        }
        if(isset($sign_array['apiEKey'])){$sign_first .= $sign_array['apiEKey'];}
//        print_r($sign_first . "\n");
        //md5
        $sign_first = md5($sign_first);
//        print_r($sign_first . "\n");
        //upper
        $sign_final = strtoupper($sign_first);
//        print_r($sign_final . "\n");
        return $sign_final;
    }
    public static function repeatCurl($url,$request_array,$ispost){
        $request_again = true;
        $request_num = 1;
        $result = ['status'=>0,'result'=>'request_fail'];
        do{
//            print_r(json_encode(['request_num'=>$request_num,'request_params'=>json_encode([$url,$request_array])]) . "\n");
            Log::info(['request_num'=>$request_num,'request_params'=>[$url,$request_array]]);
            try {
                $response = Common::commonCurl($url, $request_array,$ispost);
            }catch(Exception $e){
//                print_r(json_encode(['curl_exception'=>$e->getMessage()]) . "\n");
                $request_num += 1;
                if($request_num < 3) {
                    sleep(10);
                }
            }
            if(isset($response)){
                $response = json_decode($response);
                if(!is_null($response)) {
                    if ($response->status == 1) {
                            $result['status'] = 1;
                        if(!$ispost){
                            $result['result'] = $response->data;
                        }else {
                            $result['result'] = $response;
                        }
                    } else {
                        $result['status'] = -1;
                        $result['result'] = $response->reason;
                    }
                    $request_again = false;
                }else{
//                    print_r(json_encode(['request_result'=>'result_not_json']) . "\n");
                    $request_num += 1;
                    if($request_num < 3) {
                        sleep(10);
                    }
                }
            }
        }while($request_again && $request_num <= 3);
//        $result1 = $result;
//        print_r(json_encode($result1) . "\n");
        return $result;
    }
    public static function commonCurl($url, $params = false, $ispost = false, $https = 0)
    {
        Log::debug(['$url'=>$url,'$params'=>$params,'$ispost'=>$ispost]);
        $httpInfo = array();
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if ($https) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
        }
        if ($ispost) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
            curl_setopt($ch, CURLOPT_URL, $url);
        } else {
            if ($params) {
                if (is_array($params)) {
                    $params = http_build_query($params);
                }
                curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
            } else {
                curl_setopt($ch, CURLOPT_URL, $url);
            }
        }

        $response = curl_exec($ch);

        if ($response === FALSE) {
            //echo "cURL Error: " . curl_error($ch);
            return false;
        }
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
        curl_close($ch);
        $response1 = $response;
//        print_r(json_encode(['curl_result'=>$response1]) . "\n");
        Log::debug(['curl_result'=>$response1,'$httpInfo'=>$httpInfo]);
        return $response;
    }
    /**
     * @Author:      lyt
     * @DateTime:    2016-11-23 17:40:00
     * @Description: 抽奖程序
     */
    public static function random($ps){
        $arr=array();
        $max = array_sum($ps);
        foreach ($ps as $k=>$v) {
            $v = $v / $max * 1000000;
            for ($i=0; $i<$v; $i++)
                $arr[] = $k;
        }
        return $arr[mt_rand(0,count($arr)-1)];
    }

     /**
     * rsa私钥解密
     * @param $encrypted
     * @return string
     */
    public static function  private_decode($encrypted,$private_key)
    {
        $decrypted="";
        $pi_key=openssl_pkey_get_private($private_key);
        openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key);//私钥解密
        return $decrypted;
    }

    /**
     * @Author   lyt                      <ahlyt@anhuibj.com>
     * @DateTime 2018-04-20T09:54:43+0800
     * @param    [String]                   $data               [解密数据]
     * @param    [String]                   $key                [key]
     * @return   [String]                                       [解密内容]
     * aes 解密
     */
    public static function aes_decode($data,$key) {
        $iv = mb_substr($data,0,16,'latin1');
        $jiemi=mcrypt_decrypt(MCRYPT_RIJNDAEL_128,$key,Common::hexToStr($data),MCRYPT_MODE_ECB,$iv);
        return  Common::trimEnd($jiemi);
    }

    public static function hexToStr($hex)
    {
        $bin="";
        for($i=0; $i<strlen($hex)-1; $i+=2)
        {
            $bin.=chr(hexdec($hex[$i].$hex[$i+1]));
        }
        return $bin;
    }

    public static function trimEnd($text){
        $len = strlen($text);
        $c = $text[$len-1];
        if(ord($c) <$len){
            for($i=$len-ord($c); $i<$len; $i++){
                if($text[$i] != $c){
                    return $text;
                }
            }
            return substr($text, 0, $len-ord($c));
        }
        return $text;
    }
    
    /**
     * 二维数组排序
     * @Author:      zk
     * @DateTime:    18-4-19 下午6:11
     * @param array $arrays         待排序的二维数组
     * @param string $sort_key      排序的key
     * @param string $sort_order    排序的方式 [SORT_ASC - 默认，按升序排列; SORT_DESC - 按降序排列]
     * @param string $sort_type     排序的类型 [SORT_REGULAR -默认，将每一项按常规顺序排列;SORT_NUMERIC - 将每一项按数字顺序排列;SORT_STRING - 将每一项按字母顺序排列]
     * @return array | boolean
     */
    public static function multisort($arrays, $sort_key, $sort_order=SORT_ASC, $sort_type=SORT_NUMERIC ){
        if(is_array($arrays)){
            foreach ($arrays as $array){
                if(is_array($array)){
                    $key_arrays[] = $array[$sort_key];
                }else{
                    return false;
                }
            }
        }else{
            return false;
        }
        array_multisort($key_arrays,$sort_order,$sort_type,$arrays);
        return $arrays;
    }
}

